package com.smartmail.receiving.imap;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.util.Log;

import com.smartmail.accounts.MailAccount;
import com.smartmail.receiving.AbstractRetrievalThread;
import com.smartmail.receiving.IncomingMailDBManager;

/**
 * IMAPRetrievalThread object is object connecting with IMAP mailbox.
 * Each object of this class has ScheduledExecutorService (getScheduler method)
 * object to which you can send a request to perform tasks on IMAPMailbox.
 * 
 * These tasks can be stopped and resumed by appropriate methods ( stopThread, resumeThread)
 * 
 * @author Tomek
 *
 */
public class IMAPRetrievalThread extends AbstractRetrievalThread {


	/**
	 * Public constructor. 
	 * 
	 * @param account - MailAccount object which identities mailbox which will be handled by this thread
	 * @param manager - incoming mails database manager
	 * @param context - application context
	 */
	public IMAPRetrievalThread(MailAccount account,IncomingMailDBManager manager,Context context){
		
		super(account,manager,context);
		
		/**
		 * new single thread executor service 
		 * - one thread for checking mailbox
		 */
		_executor = Executors.newScheduledThreadPool(1);
		
		/**
		 * new single thread executor service 
		 * - one thread for listening mailbox imap
		 */
		_listeningExecutor = null;
		
		_checkMailboxTasksFutures = new ArrayList<ScheduledFuture>();
		
	}
	
	/**
	 * 
	 * Resume execution of tasks for this thread
	 * 
	 * @return - true on success, otherwise false.
	 *
	 */
	@Override

	public boolean resumeThread() {

		if( _executor.isShutdown())
			return false;
		
		for(ScheduledFuture checkMailboxFuture : _checkMailboxTasksFutures){
			
			checkMailboxFuture.cancel(true);
		}
		_checkMailboxTasksFutures.clear();
		
		
		//create new single threaded executor
		_listeningExecutor = Executors.newScheduledThreadPool(1);
		
		//cancel old listening task
		if(_listeningTask != null){
			
			if(_listeningTask.cancel(true))
				Log.d(_logTag, "listening task canceled " + _mailAccount.getMailAddress());
			else
				Log.d(_logTag, "listening task not canceled " + _mailAccount.getMailAddress());
		}
		
		
		ScheduledFuture _checkMailboxFuture = 
				_executor.schedule(new IMAPSynchronizeTask(_mailAccount,_context), 1, TimeUnit.SECONDS);
		_checkMailboxTasksFutures.add(_checkMailboxFuture);
		
		_listeningTask = _listeningExecutor.schedule(new IMAPListenMailboxTask(_mailAccount, _context), 1, TimeUnit.SECONDS);
		
		return true;

	}

	

	@Override
	public boolean killThread() {
		
		stopThread();
		_executor.shutdownNow();
		
		if(_listeningExecutor != null)
			_listeningExecutor.shutdownNow();
	
		return true;
	}

	@Override
	public boolean stopThread() {

		if( _executor.isShutdown() )
			return false;
		
		for(ScheduledFuture checkMailboxFuture : _checkMailboxTasksFutures){
			
			checkMailboxFuture.cancel(true);
		}
		_checkMailboxTasksFutures.clear();
		

		if(_listeningTask != null){
			
			if(_listeningTask.cancel(true))
				Log.d(_logTag, "listening task canceled 2 " + _mailAccount.getMailAddress());
			else
				Log.d(_logTag, "listening task not canceled 2" + _mailAccount.getMailAddress());
		}
		
		// mark that listening task is canceled
		_listeningTask = null;
		
		if(_listeningExecutor != null){
			
			_listeningExecutor.shutdownNow();
			_listeningExecutor = null;
		}
		
		return true;
		
	}

	@Override
	public boolean isRunning() {

		if( _listeningTask == null)
			return false;
		
		return ( !_listeningTask.isCancelled() );
	}

	@Override
	public boolean restartThread() {

		if(stopThread())
			if(resumeThread())
					return true;
		return false;
	}
	
	@Override
	public void checkMailbox() {
		
		ScheduledFuture _checkMailboxFuture = 
				_executor.schedule(new IMAPSynchronizeTask(_mailAccount,_context), 0, TimeUnit.SECONDS);
		_checkMailboxTasksFutures.add(_checkMailboxFuture);
		
	}
	
	@Override
	public void downloadMessages() {

		Log.d(_logTag,"IMAPRetrievalThread : in IMAP protocol downloading on demand unsupported");
		
	}
	
	/**
	 * logTag for logging purposes
	 */
	private static String _logTag = "com.smartmail.receiving.imap";
	
	/**
	 * Scheduled executor only for imap listening task
	 */
	private ScheduledExecutorService _listeningExecutor;
	
	/**
	 * List of check mailbox tasks futures.
	 */
	private List<ScheduledFuture> _checkMailboxTasksFutures;

	
	/**
	 * Scheduled Future of continuous listening
	 */
	private ScheduledFuture _listeningTask = null;


	


	
	

}
